package com.pn.service.impl;

import com.alibaba.fastjson.JSON;
import com.pn.mapper.AuthInfoMapper;
import com.pn.model.AuthInfo;
import com.pn.service.AuthInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * ClassName:AuthInfoServiceImpl
 * Package:com.pn.service.impl
 * Description:
 *
 * @date:2024/12/28 17:10
 * @author:bailihua
 */
@CacheConfig(cacheNames = "com.pn.service.impl.AuthInfoServiceImpl")
@Service
public class AuthInfoServiceImpl implements AuthInfoService {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private AuthInfoMapper authInfoMapper;

    /**
     * 查询用户菜单树的业务方法
     * 向redis缓存用户菜单树--键authTree：userId 值菜单树List<AuthInfo>转的json串
     * @param userId
     * @return
     */
    @Override
    public List<AuthInfo> queryAuthTreeById(int userId) {

        //先从redis中查询缓存的用户菜单树
        String authTreeJson = stringRedisTemplate.opsForValue().get("authTree:"+userId);
        if(StringUtils.hasText(authTreeJson)){//说明redis中有用户菜单树的缓存
            //将菜单树List<AuthInfo> 转的json串转回菜单树List<AuthInfo>并返回
            List<AuthInfo> authTreeList = JSON.parseArray(authTreeJson,AuthInfo.class);
            return authTreeList;
        }
        //说明redis中没有用户菜单树的缓存
        //查询用户权限下的所有菜单
        List<AuthInfo> allAuthList = authInfoMapper.findAuthByUid(userId);
        //将所有菜单List<AuthINfo>转换为菜单树
        List<AuthInfo> authTreeList = allAuthToAuthTree(allAuthList,0);
        //向redis中缓存菜单树List
        stringRedisTemplate.opsForValue().set("authTree:"+userId,JSON.toJSONString(authTreeList));
        return authTreeList;
    }



    //将所有菜单List<AuthInfo>转换成菜单树的递归算法
    private List<AuthInfo> allAuthToAuthTree(List<AuthInfo> allAuthList,Integer pid){
        //查询出所有一级菜单
        List<AuthInfo> firstLevelAuthList = new ArrayList<>();
        for (AuthInfo auth : allAuthList) {
            if(auth.getParentId().equals(pid)){
                firstLevelAuthList.add(auth);
            }
        }
        
        //拿到每个一级菜单的所有二级菜单
        for (AuthInfo firstAuth : firstLevelAuthList) {
            List<AuthInfo> secondLevelAuthList = allAuthToAuthTree(allAuthList,firstAuth.getAuthId());
            firstAuth.setChildAuth(secondLevelAuthList);
        }

        return firstLevelAuthList;
    }

    /**
     * 查询所有权限菜单树
     * @return
     */
    @Cacheable(key = "'all:authTree'")
    @Override
    public List<AuthInfo> allAuthTree() {
        //查询所有权限菜单树
        List<AuthInfo> allAuthList = authInfoMapper.findAllAuth();
        //将所有权限菜单List转换为权限菜单树List
        List<AuthInfo> authTreeList = allAuthToAuthTree(allAuthList,0);
        return authTreeList;
    }
}
